home *** CD-ROM | disk | FTP | other *** search
Text File | 1999-06-16 | 18.3 KB | 715 lines | [TEXT/MPS ] |
- /*
- File: document.c
-
- Copyright: © 1997-1998 by Apple Computer, Inc., all rights reserved.
-
- */
-
- //
- // You may incorporate this sample code into your applications
- // without restriction. This sample code has been provided "AS
- // IS" and the responsibility for its operation is 100% yours.
- // You are not permitted to redistribute the source as "Apple
- // sample code" after having made changes. If you're going to
- // re-distribute the source, we require that you make it clear
- // in the source that the code was descended from Apple sample
- // code, but that you've made changes.
- //
-
- #pragma segment DocSeg
-
- #ifndef __DRAG__
- #include <Drag.h>
- #endif
-
- #ifndef __TOOLUTILS__
- #include <ToolUtils.h>
- #endif
-
- #ifndef __STDIO__
- #include <Stdio.h>
- #endif
-
- #ifndef Common_Defs
- #include "Common.h"
- #endif
-
- #ifndef __NAVIGATION__
- #include "Navigation.h"
- #endif
-
- const printID = -8192; // string rsrc ID if print driver name
- const OSType strType = 'STR '; // string resource type
-
- extern short gDocumentCount;
- extern Document* gDocumentList[kMaxDocumentCount];
- extern short gQuitting;
- extern short gCanUndoDrag;
- extern WindowPtr gUndoFrontmost, gLastFrontmost;
- extern Boolean gCanDrag;
- extern Boolean gNavServicesExists;
-
- extern pascal OSErr MyTrackingHandler(short message, WindowPtr theWindow, void* handlerRefCon, DragReference theDrag);
- extern pascal OSErr MyReceiveDropHandler(WindowPtr theWindow, unsigned long handlerRefCon, DragReference theDrag);
-
- void PositionDocumentParts(Document* theDocument);
- void DoDrawGrowIcon(WindowPtr theWindow);
-
- DragReceiveHandlerUPP receiveHandler;
- DragTrackingHandlerUPP trackingHandler;
- DragSendDataUPP sendHandler;
-
- pascal void myventProc(const NavEventCallbackMessage callBackSelctor,
- NavCBRecPtr callBackParms,
- NavCallBackUserData callBackUD);
- NavAskSaveChangesResult OpenAskSaveChanges(unsigned char* docName, Boolean quitting);
-
-
- // **********************************************************************
- // *
- // * AddText()
- // *
- // **********************************************************************
- void AddText(Document* theDocument, Ptr text, long len)
- {
- if (theDocument->theTE != NULL)
- {
- TEInsert(text,len,theDocument->theTE);
- theDocument->dirty = true;
- TESelView(theDocument->theTE);
- AdjustScrollBar((Document*)GetWRefCon(theDocument->theWindow));
- }
- }
-
-
- // **********************************************************************
- // *
- // * AdjustDocumentView()
- // *
- // **********************************************************************
- void AdjustDocumentView(Document* theDocument)
- {
- short delta, docTop, docTopLimit;
-
- delta = (theDocument->vScrollPos - GetControlValue(theDocument->vScroll)) * ScrollResolution;
-
- if (delta && theDocument->theTE)
- {
- if (delta > 0)
- {
- docTop = (**(theDocument->theTE)).destRect.top;
- docTopLimit = (**(theDocument->theTE)).viewRect.top + TopMargin;
- if (docTop + delta > docTopLimit)
- delta = docTopLimit - docTop;
- }
- TEScroll(0,delta,theDocument->theTE);
- theDocument->vScrollPos = GetControlValue(theDocument->vScroll);
- }
- }
-
-
- // **********************************************************************
- // *
- // * AdjustScrollBar()
- // *
- // **********************************************************************
- void AdjustScrollBar(Document* theDocument)
- {
- short docTop, docBottom, viewTop, viewBottom;
- short offTop, offBottom;
- RgnHandle viewRgn;
-
- if (theDocument->theTE != NULL)
- {
- docTop = (**(theDocument->theTE)).destRect.top;
- docBottom = docTop + TEGetHeight(32767,0,theDocument->theTE);
- viewTop = (**(theDocument->theTE)).viewRect.top;
- viewBottom = (**(theDocument->theTE)).viewRect.bottom;
-
- offTop = ((viewTop - (docTop - TopMargin)) + ScrollResolution - 1) / ScrollResolution;
- offBottom = (((docBottom + BottomMargin) - viewBottom) + ScrollResolution - 1) / ScrollResolution;
- if (offTop < 0)
- offTop = 0;
- if (offBottom < 0)
- offBottom = 0;
-
- theDocument->vScrollPos = offTop;
-
- SetControlMaximum(theDocument->vScroll,offTop + offBottom);
- SetControlValue(theDocument->vScroll,offTop);
-
- viewRgn = NewRgn();
- RectRgn(viewRgn,&(**(theDocument->theTE)).viewRect);
- SectRgn(viewRgn,theDocument->hiliteRgn,theDocument->hiliteRgn);
- DisposeRgn(viewRgn);
- }
- }
-
-
- // **********************************************************************
- // *
- // * PositionDocumentParts()
- // *
- // **********************************************************************
- void PositionDocumentParts(Document* theDocument)
- {
- Rect globalBounds = theDocument->theWindow->portRect;
- Rect theRect;
-
- // size the vertical scrollbar:
- SizeControl(theDocument->vScroll,kScrollBarWidth,(globalBounds.bottom - globalBounds.top - kScrollBarPos)+4);
- MoveControl(theDocument->vScroll,globalBounds.right+2 - kScrollBarPos,-1);
-
- // size the horizontal scrollbar:
- SizeControl(theDocument->hScroll,(globalBounds.right - globalBounds.left - kScrollBarPos)+4,kScrollBarWidth);
- MoveControl(theDocument->hScroll,-1,(globalBounds.bottom - globalBounds.top - kScrollBarPos)+2);
-
- theRect = globalBounds;
- theRect.right -= 15;
- theRect.bottom -= 15;
- (**(theDocument->theTE)).viewRect = theRect;
- (**(theDocument->theTE)).destRect.right = theRect.right - RightMargin;
- TECalText(theDocument->theTE);
- }
-
-
- void SizeDocWindow(Document* theDocument)
- {
- short length = 0;
- short width = 0;
- if (theDocument->fPict != NULL)
- {
- if ((**((PicHandle)theDocument->fPict)).picFrame.right >= qd.screenBits.bounds.right)
- width = qd.screenBits.bounds.right-40;
- else
- width = (**((PicHandle)theDocument->fPict)).picFrame.right;
-
- if ((**((PicHandle)theDocument->fPict)).picFrame.bottom >= qd.screenBits.bounds.bottom)
- length = qd.screenBits.bounds.bottom-10-LMGetMBarHeight()-27;
- else
- length = (**((PicHandle)theDocument->fPict)).picFrame.bottom;
- }
- else
- {
- length = qd.screenBits.bounds.bottom-10-LMGetMBarHeight()-27;
- width = kWindowWidth;
- }
- SizeWindow(theDocument->theWindow,width,length,true);
- }
-
-
- // **********************************************************************
- // *
- // * NewDocument()
- // *
- // **********************************************************************
- Document* NewDocument(Boolean newDocAsPICT)
- {
- OSErr theErr = noErr;
- Document* theDocument;
- WindowPtr theWindow;
- Rect theRect = {0,0,16,16};
- TextStyle theStyle;
- TEStyleHandle theStyleHandle;
- Point thePoint;
- Rect theSize;
- short length = 0, width = 0;
- Str255 windTitle;
- short offset;
- Rect bounds;
-
- if (gDocumentCount == kMaxDocumentCount)
- return ((Document*)0L);
-
- theDocument = gDocumentList[gDocumentCount++] = (Document*)NewPtr(sizeof(Document));
-
- // create the window
- offset = gDocumentCount-1;
- theDocument->theWindow = theWindow = NewCWindow(0L,&theSize,(unsigned char*)"\p",false,zoomDocProc,(WindowPtr)-1L,true,0L);
- MoveWindow(theDocument->theWindow,(10+(offset*20)),(27+(offset*20)+LMGetMBarHeight()),true);
-
- bounds = theWindow->portRect;
-
- // setup the window title
- sprintf((char*)windTitle,"untitled %d",gDocumentCount);
- MyC2PStr((char*)windTitle);
- SetWTitle(theDocument->theWindow,windTitle);
-
- SetWRefCon(theWindow,(long)theDocument);
-
- SetPort(theWindow);
- thePoint.v = bounds.top;
- thePoint.h = bounds.left;
-
- LocalToGlobal(&thePoint);
- if (thePoint.h < 10)
- MoveWindow(theWindow,InitialH,InitialV,false);
-
- if (newDocAsPICT)
- {
- theDocument->theTE = NULL;
- theDocument->fPict = NULL;
- theDocument->fPictLength = 0;
- theDocument->fHeader = NULL;
- }
- else
- {
- theDocument->fPict = NULL;
-
- SizeDocWindow(theDocument);
-
- theDocument->vScroll = NewControl(theWindow,&theRect,(ConstStr255Param)"\p",true,0,0,0,scrollBarProc,(long)theDocument);
- theDocument->hScroll = NewControl(theWindow,&theRect,(ConstStr255Param)"\p",true,0,0,0,scrollBarProc,(long)theDocument);
-
- theDocument->theTE = TEStyleNew(&theRect,&theRect);
- (**(theDocument->theTE)).destRect.top = TopMargin;
- (**(theDocument->theTE)).destRect.left = LeftMargin;
- (**(theDocument->theTE)).destRect.bottom = 32767;
-
- TEAutoView(true,theDocument->theTE);
-
- TEFeatureFlag(teFOutlineHilite,teBitSet,theDocument->theTE);
-
- theDocument->hiliteRgn = NewRgn();
- theStyleHandle = TEGetStyleHandle(theDocument->theTE);
- (**theStyleHandle).teRefCon = (long)theDocument;
-
- theStyle.tsFont = 21;
- theStyle.tsSize = 12;
- TESetStyle(doFont + doSize,&theStyle,false,theDocument->theTE);
-
- theDocument->vScrollPos = 0;
- theDocument->undoDragText = 0L;
-
- PositionDocumentParts(theDocument);
-
- if (gCanDrag && theDocument->theTE != NULL)
- {
- receiveHandler = NewDragReceiveHandlerProc(&MyReceiveDropHandler);
- trackingHandler = NewDragTrackingHandlerProc(&MyTrackingHandler);
-
- theErr = InstallReceiveHandler(receiveHandler,theWindow,(void*)theDocument);
- theErr = InstallTrackingHandler(trackingHandler,theWindow,(void*)theDocument);
- }
- }
-
- theDocument->fRefNum = 0;
- theDocument->dirty = false;
-
- return theDocument;
- }
-
-
- // **********************************************************************
- // *
- // * OpenAskSaveChanges()
- // *
- // **********************************************************************
- NavAskSaveChangesResult OpenAskSaveChanges(unsigned char* docName, Boolean quitting)
- {
- OSStatus theStatusErr = noErr;
- OSErr theErr = noErr;
- NavAskSaveChangesResult reply = 0;
- NavAskSaveChangesAction action = 0;
- NavEventUPP eventUPP = NewNavEventProc(myEventProc);
- NavDialogOptions dialogOptions;
-
- if (quitting)
- action = kNavSaveChangesQuittingApplication;
- else
- action = kNavSaveChangesClosingDocument;
-
- BlockMoveData(docName,dialogOptions.savedFileName,docName[0]+1);
- GetIndString(dialogOptions.clientName,rAppStringsID,sApplicationName);
-
- theErr = NavAskSaveChanges( &dialogOptions,
- action,
- &reply,
- eventUPP,
- (NavCallBackUserData)&gDocumentList);
-
- DisposeRoutineDescriptor(eventUPP);
-
- return reply;
- }
-
-
- // **********************************************************************
- // *
- // * CloseDocument()
- // *
- // **********************************************************************
- void CloseDocument(Document* theDocument, Boolean quitting)
- {
- OSErr theErr = noErr;
- short index;
- Str255 theName;
-
- index = 0;
- while ((gDocumentList[index] != theDocument) && (index < kMaxDocumentCount))
- index++;
-
- if (gDocumentList[index] == theDocument)
- {
- if (theDocument->dirty)
- {
- if (gNavServicesExists)
- {
- NavAskSaveChangesResult result = 0;
- GetWTitle(theDocument->theWindow,(unsigned char*)&theName);
- result = OpenAskSaveChanges(theName,quitting);
- switch (result)
- {
- case kNavAskSaveChangesSave:
- if (!DoSaveDocument(theDocument))
- {
- gQuitting = false; // don't quit yet!
- //return;
- }
- break;
- case kNavAskSaveChangesCancel:
- gQuitting = false; // don't quit yet!
- //return;
- break;
- }
- if (result == kNavAskSaveChangesCancel)
- return; // don't close the document
- }
- else
- {
- short response = 0;
- Str255 theVerb;
- GetWTitle(theDocument->theWindow,(unsigned char*)&theName);
- GetIndString((unsigned char*)&theVerb,rAppStringsID,(gQuitting) ? slQuittingIndex : slClosingIndex);
- ParamText((ConstStr255Param)&theName,(ConstStr255Param)&theVerb,(ConstStr255Param)"\p",(ConstStr255Param)"\p");
- SetCursor(&qd.arrow);
- response = Alert(rSaveChangesID,0L);
-
- if (response == 1)
- { // Save
- if (!DoSaveDocument(theDocument))
- {
- gQuitting = false;
- return;
- }
- }
- else
- if (response == 3)
- { // Don't Save
- ;
- }
- else
- { // Cancel
- gQuitting = false;
- return;
- }
- }
- }
-
- if (theDocument->fRefNum)
- FSClose(theDocument->fRefNum);
-
- if (gCanDrag && theDocument->theTE != NULL)
- {
- theErr = RemoveReceiveHandler(receiveHandler,theDocument->theWindow);
- theErr = RemoveTrackingHandler(trackingHandler,theDocument->theWindow);
- }
-
- if (theDocument->theTE != NULL)
- {
- DisposeRgn(theDocument->hiliteRgn);
- TEDispose(theDocument->theTE);
-
- if (theDocument->undoDragText)
- {
- DisposeHandle(theDocument->undoDragText);
- theDocument->undoDragText = 0L;
- }
- }
- else
- {
- if (theDocument->fPict != NULL)
- KillPicture((PicHandle)theDocument->fPict);
- if (theDocument->fHeader != NULL)
- DisposeHandle(theDocument->fHeader);
- }
-
- DisposeWindow(theDocument->theWindow);
-
- while (index < kMaxDocumentCount)
- {
- gDocumentList[index] = gDocumentList[index + 1];
- index++;
- }
-
- DisposePtr((Ptr)theDocument);
- gDocumentCount--;
- }
- }
-
-
- // **********************************************************************
- // *
- // * DoActivateDocument()
- // *
- // **********************************************************************
- void DoActivateDocument(Document* theDocument, short activate)
- {
- if (theDocument->theTE != NULL)
- {
- if (activate)
- {
- TEActivate(theDocument->theTE);
- HiliteControl(theDocument->vScroll,0);
- HiliteControl(theDocument->hScroll,0);
- DoDrawGrowIcon(theDocument->theWindow);
- TEGetHiliteRgn(theDocument->hiliteRgn,theDocument->theTE);
- }
- else
- {
- TEDeactivate(theDocument->theTE);
- HiliteControl(theDocument->vScroll,255);
- HiliteControl(theDocument->hScroll,255);
- DoDrawGrowIcon(theDocument->theWindow);
- }
- }
- }
-
-
- // **********************************************************************
- // *
- // * IsDocumentWindow()
- // *
- // **********************************************************************
- Document* IsDocumentWindow(WindowPtr theWindow)
- {
- short index = 0;
- Document* theDocument;
-
- theDocument = (Document*)GetWRefCon(theWindow);
-
- while ((gDocumentList[index] != theDocument) && (index < gDocumentCount))
- index++;
-
- if (gDocumentList[index] == theDocument)
- return(theDocument);
- else
- return((Document*)0L);
- }
-
-
- // **********************************************************************
- // *
- // * DoSelectAllDocument()
- // *
- // **********************************************************************
- void DoSelectAllDocument(Document* theDocument)
- {
- if (theDocument && (theDocument->theTE))
- TESetSelect(0,32767,theDocument->theTE);
- }
-
-
- // **********************************************************************
- // *
- // * DisableUndoDrag()
- // *
- // **********************************************************************
- void DisableUndoDrag()
- {
- short index;
- Document* theDoc;
-
- gCanUndoDrag = slCantUndo;
-
- index = gDocumentCount;
- while (index--)
- {
- theDoc = gDocumentList[index];
- if (theDoc->undoDragText)
- {
- DisposeHandle(theDoc->undoDragText);
- theDoc->undoDragText = 0L;
- }
- }
- }
-
-
- // **********************************************************************
- // *
- // * DoUndoDrag()
- // *
- // **********************************************************************
- void DoUndoDrag()
- {
- short index, selStart, selEnd;
- Document* theDoc;
- Handle theText;
- WindowPtr theWindow;
- Rect theRect;
-
- if (gCanUndoDrag != slCantUndo)
- {
- theWindow = 0L;
- index = gDocumentCount;
- while (index--)
- {
- theDoc = gDocumentList[index];
-
- SetPort(theDoc->theWindow);
-
- if (theText = theDoc->undoDragText)
- {
- Rect bounds = theDoc->theWindow->portRect;
-
- theDoc->undoDragText = (**theDoc->theTE).hText;
- (**theDoc->theTE).hText = theText;
-
- TECalText(theDoc->theTE);
-
- selStart = theDoc->undoSelStart;
- selEnd = theDoc->undoSelEnd;
- TESetSelect(selStart,selEnd,theDoc->theTE);
- theDoc->undoSelStart = theDoc->lastSelStart;
- theDoc->undoSelEnd = theDoc->lastSelEnd;
- theDoc->lastSelStart = selStart;
- theDoc->lastSelEnd = selEnd;
-
- theRect = bounds;
- theRect.right -= 15;
- theRect.bottom -= 15;
- EraseRect(&theRect);
- TEUpdate(&theRect,theDoc->theTE);
- }
- }
-
- if (gCanUndoDrag == slUndoDrag)
- gCanUndoDrag = slRedoDrag;
- else
- gCanUndoDrag = slUndoDrag;
-
- theWindow = gUndoFrontmost;
- gUndoFrontmost = gLastFrontmost;
- gLastFrontmost = theWindow;
- }
- }
-
-
- // *****************************************************************************
- // *
- // * DoDrawGrowIcon()
- // *
- // *****************************************************************************
- void DoDrawGrowIcon(WindowPtr theWindow)
- {
- RgnHandle saveClipRgn = NewRgn();
- Rect tempRect;
-
- if (saveClipRgn)
- {
- GetClip(saveClipRgn);
-
- SetRect(&tempRect,
- theWindow->portRect.right-15,
- theWindow->portRect.bottom-15,
- theWindow->portRect.right,
- theWindow->portRect.bottom);
- ClipRect(&tempRect);
- DrawGrowIcon(theWindow);
-
- SetClip(saveClipRgn);
- DisposeRgn(saveClipRgn);
- }
- else
- DrawGrowIcon(theWindow);
- }
-
-
- // *****************************************************************************
- // *
- // * UpdateWindow()
- // *
- // * Update event is received for a document window.
- // *
- // *****************************************************************************
- void UpdateWindow(Document* theDocument)
- {
- WindowPtr theWindow = theDocument->theWindow;
- Rect bounds = theDocument->theWindow->portRect;
-
- SetPort(theWindow);
-
- BeginUpdate(theWindow);
-
- EraseRect(&bounds);
- if (theDocument->theTE != NULL)
- {
- DrawControls(theWindow);
- DoDrawGrowIcon(theWindow);
- if (theDocument->theTE)
- TEUpdate(&bounds,theDocument->theTE);
- }
- else
- {
- if (theDocument->fPict != NULL)
- DrawPicture((PicHandle)theDocument->fPict,&((**((PicHandle)theDocument->fPict)).picFrame));
- }
- EndUpdate(theWindow);
- }
-
-
- // *****************************************************************************
- // *
- // * DoZoomDocument()
- // *
- // *****************************************************************************
- void DoZoomDocument(Document* theDocument, WindowPtr theWindow, short thePart)
- {
- GrafPtr oldPort;
- GetPort(&oldPort);
-
- SetPort(theWindow);
- EraseRect(&theWindow->portRect);
- ZoomWindow(theWindow,thePart,theWindow == FrontWindow());
-
- if (theDocument->theTE != NULL)
- {
- PositionDocumentParts((Document*)GetWRefCon(theWindow));
- AdjustScrollBar((Document*)GetWRefCon(theWindow));
- DoDrawGrowIcon(theWindow);
- }
-
- InvalRect(&theWindow->portRect);
-
- SetPort(oldPort);
- }
-
-
- // *****************************************************************************
- // *
- // * GrowDocumentWindow()
- // *
- // *****************************************************************************
- void GrowDocumentWindow(WindowPtr theWindow, Point thePoint)
- {
- long result;
- Rect sizeRect;
- Rect bounds = theWindow->portRect;
-
- SetPort(theWindow);
-
- sizeRect = qd.screenBits.bounds;
- if (!(result = GrowWindow(theWindow,thePoint,&sizeRect)))
- return;
-
- SizeWindow(theWindow,LoWord(result),HiWord(result),false);
-
- PositionDocumentParts((Document*)GetWRefCon(theWindow));
-
- AdjustScrollBar((Document*)GetWRefCon(theWindow));
-
- DoDrawGrowIcon(theWindow);
-
- bounds = theWindow->portRect;
- InvalRect(&bounds);
- }